package com.yanqu.road.entity.activity.hsisland.config;

import com.yanqu.road.entity.activity.hsisland.HsIslandPosition;
import com.yanqu.road.entity.FieldTypeAnnotation;
import com.yanqu.road.entity.activity.hsisland.data.HsIslandBoxData;
import com.yanqu.road.entity.activity.hsisland.enums.HsIslandLatticeTypeEnum;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.plot.PlotUtil;
import com.yanqu.road.utils.plot.Point;
import com.yanqu.road.utils.plot.PointFjd;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.Types;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@FieldTypeAnnotation(tableName = "t_s_activity_hsisland_island")
public class HsIslandIslandConfig {

    @FieldTypeAnnotation(desc = "活动id", select = true, update = true)
    private int activityId;

    @FieldTypeAnnotation(desc = "ID", select = true, update = true)
    private int id;

    @FieldTypeAnnotation(desc = "格子分布参数", sqlType = Types.LONGVARCHAR)
    private String latticeParam;
    private Map<Integer, Integer> latticeParamMap;//k：事件id，v：个数

    @FieldTypeAnnotation(desc = "格子分布权重参数(事件id;权重|事件id;权重)", sqlType = Types.LONGVARCHAR)
    private String latticeWeight;
    private Map<Integer, Integer> latticeWeightMap;//k：事件id，v：权重

    @FieldTypeAnnotation(desc = "四个PVE事件数量")
    private int bigPveNum;

    @FieldTypeAnnotation(desc = "事件总数量")
    private int allEventNum;

    @FieldTypeAnnotation(desc = "地图类型")
    private int mapType;

    @FieldTypeAnnotation(desc = "地图分布参数", sqlType = Types.LONGVARCHAR)
    private String mapParam;
    private Map<Integer, Set<String>> mapTypeParamMap = new HashMap<>();//k：类型，v：坐标集合
    private Map<String, Integer> mapParamMap = new HashMap<>();//k：坐标，v：类型

    @FieldTypeAnnotation(desc = "地图图片资源参数", sqlType = Types.LONGVARCHAR)
    private String pngParam;

    @FieldTypeAnnotation(desc = "岛屿权重")
    private int weight;

    public int getActivityId() {
        return activityId;
    }

    public void setActivityId(int activityId) {
        this.activityId = activityId;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getLatticeParam() {
        return latticeParam;
    }

    public void setLatticeParam(String latticeParam) {
        this.latticeParam = latticeParam;
        //解析一下
        Map<Integer, Integer> latticeParamMap = new HashMap<>();
        if (!StringUtils.isNullOrEmpty(latticeParam)) {
            String[] eventArr = latticeParam.split("\\|");
            for (String eventStr : eventArr) {
                String[] itemArr = eventStr.split(";");
                int eventId = Integer.parseInt(itemArr[0]);
                int num = Integer.parseInt(itemArr[1]);
                latticeParamMap.put(eventId, num);
            }
        }
        this.latticeParamMap = latticeParamMap;
    }

    public Map<Integer, Integer> getLatticeParamMap() {
        return latticeParamMap;
    }

    public String getLatticeWeight() {
        return latticeWeight;
    }

    public void setLatticeWeight(String latticeWeight) {
        this.latticeWeight = latticeWeight;
        //解析一下
        Map<Integer, Integer> latticeWeightMap = new HashMap<>();
        if (!StringUtils.isNullOrEmpty(latticeWeight)) {
            String[] eventArr = latticeWeight.split("\\|");
            for (String eventStr : eventArr) {
                String[] itemArr = eventStr.split(";");
                int eventId = Integer.parseInt(itemArr[0]);
                int num = Integer.parseInt(itemArr[1]);
                latticeWeightMap.put(eventId, num);
            }
        }
        this.latticeWeightMap = latticeWeightMap;
    }

    public Map<Integer, Integer> getLatticeWeightMap() {
        return latticeWeightMap;
    }

    public int getBigPveNum() {
        return bigPveNum;
    }

    public void setBigPveNum(int bigPveNum) {
        this.bigPveNum = bigPveNum;
    }

    public int getAllEventNum() {
        return allEventNum;
    }

    public void setAllEventNum(int allEventNum) {
        this.allEventNum = allEventNum;
    }

    public int getMapType() {
        return mapType;
    }

    public void setMapType(int mapType) {
        this.mapType = mapType;
    }

    public String getMapParam() {
        return mapParam;
    }

    public void setMapParam(String mapParam) {
        this.mapParam = mapParam;
        if (!StringUtils.isNullOrEmpty(mapParam)) {
            Map<Integer, Set<String>> mapTypeParamMap = new HashMap<>();
            Map<String, Integer> mapParamMap = new HashMap<>();
            String[] params = mapParam.split("\\|");
            for (String item : params) {
                String[] itemArr = item.split("=");
                int type = Integer.parseInt(itemArr[1]);
                String position = itemArr[0];
                Set<String> positionSet = mapTypeParamMap.computeIfAbsent(type, k -> new HashSet<>());
                positionSet.add(position);
                mapParamMap.put(position, type);
            }
            this.mapTypeParamMap = mapTypeParamMap;
            this.mapParamMap = mapParamMap;
        }
    }

    public Map<Integer, Set<String>> getMapTypeParamMap() {
        return mapTypeParamMap;
    }

    public Map<String, Integer> getMapParamMap() {
        return mapParamMap;
    }

    /**
     * 获取地块类型
     * @param position
     * @return
     */
    public Integer getPositionType(String position) {
        return mapParamMap.get(position);
    }

    public String getPngParam() {
        return pngParam;
    }

    public void setPngParam(String pngParam) {
        this.pngParam = pngParam;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    /**
     * 随机获取岛屿出生点
     * @return
     */
    public String getRandomBornPosition() {
        Set<String> latticeSet = this.mapTypeParamMap.get(HsIslandLatticeTypeEnum.LATTICE_TYPE_BORN.getType());
        if (latticeSet == null || latticeSet.isEmpty()) {
            return null;
        }
        return RandomHelper.getRandomElement(latticeSet);
    }

    /**
     * 获取宝箱坐标LIST(递归)
     * @param xLength
     * @param yLength
     * @param eventPositionSet
     * @param dgNum
     * @return
     */
    private List<int[]> getBoxPositionList(int xLength, int yLength, Set<String> eventPositionSet, int dgNum) {
        if (dgNum >= 20) {
            //递归超过20次，返回null，地图无宝箱
            return null;
        }
        //随机出一个坐标
        String startPosition = RandomHelper.getRandomElement(eventPositionSet);
        if (startPosition == null) {
            return null;
        }
        int startX = Integer.parseInt(startPosition.split(",")[0]);
        int startY = Integer.parseInt(startPosition.split(",")[1]);
        //判断坐标是否符合生成 xLength * yLength的宝箱块
        boolean flag = true;
        List<int[]> positionList = PlotUtil.generateRectangleCoordinates2(startX, startY, xLength, yLength);
        for (int[] position : positionList) {
            String checkPosition = position[0] + "," + position[1];
            if (!eventPositionSet.contains(checkPosition)) {
                flag = false;
                break;
            }
        }
        if (!flag) {
            //递归获取
            return getBoxPositionList(xLength, yLength, eventPositionSet, dgNum + 1);
        } else {
            return positionList;
        }
    }

    /**
     * 创建宝箱MAP,K:x_y
     * @return
     */
    public Map<String, HsIslandBoxData> createBoxMap(int xLength, int yLength, Map<Integer, HsIslandBoxConfig> boxConfigMap) {
        Set<String> latticeSet = this.mapTypeParamMap.get(HsIslandLatticeTypeEnum.LATTICE_TYPE_BOX.getType());
        if (latticeSet == null || latticeSet.isEmpty()) {
            return null;
        }
        //随机一个宝箱生成起始坐标
        String startPosition = RandomHelper.getRandomElement(latticeSet);
        if (startPosition == null) {
            return null;
        }
        //获取事件配置
        //生成 xLength * yLength 的宝箱格子组
        int startX = Integer.parseInt(startPosition.split(",")[0]);
        int startY = Integer.parseInt(startPosition.split(",")[1]);
        List<int[]> positionList = PlotUtil.generateRectangleCoordinates2(startX, startY, xLength, yLength);
        //创建宝箱MAP
        Map<String, HsIslandBoxData> boxMap = new HashMap<>();
        //宝箱id池子
        List<Integer> boxIdList = new ArrayList<>();
        for (HsIslandBoxConfig boxConfig : boxConfigMap.values()) {
            for (int i = 0; i < boxConfig.getNum(); i++) {
                boxIdList.add(boxConfig.getId());
            }
        }
        for (int[] position : positionList) {
            //随机出一个宝箱ID
            int boxId = 1;
            if (!boxIdList.isEmpty()) {
                boxId = RandomHelper.getRandomElementAndRemove(boxIdList);
            }
            int x = position[0];
            int y = position[1];
            String positionStr = x + "_" + y;
            HsIslandBoxData boxData = new HsIslandBoxData(boxId, x, y);
            boxMap.put(positionStr, boxData);
        }
        return boxMap;


//        Map<String, HsIslandBoxData> boxMap = new HashMap<>();
//        //事件地块
//        Set<String> eventLatticeSet = this.mapTypeParamMap.get(HsIslandLatticeTypeEnum.LATTICE_TYPE_ONE.getType());
//        if (eventLatticeSet == null || eventLatticeSet.isEmpty()) {
//            return boxMap;
//        }
//        //获取宝箱坐标LIST
//        List<int[]> positionList = this.getBoxPositionList(xLength, yLength, eventLatticeSet, 0);
//        if (positionList == null) {
//            return boxMap;
//        }
//        //宝箱id池子
//        List<Integer> boxIdList = new ArrayList<>();
//        for (HsIslandBoxConfig boxConfig : boxConfigMap.values()) {
//            for (int i = 0; i < boxConfig.getNum(); i++) {
//                boxIdList.add(boxConfig.getId());
//            }
//        }
//        for (int[] position : positionList) {
//            //随机出一个宝箱ID
//            int boxId = 1;
//            if (!boxIdList.isEmpty()) {
//                boxId = RandomHelper.getRandomElementAndRemove(boxIdList);
//            }
//            int x = position[0];
//            int y = position[1];
//            String positionStr = x + "_" + y;
//            HsIslandBoxData boxData = new HsIslandBoxData(boxId, x, y);
//            boxMap.put(positionStr, boxData);
//        }
//        return boxMap;
    }

    /**
     * 递归生成四格事件位置
     * @param targetPositionMap K：x,y，v：4个坐标
     * @param fjdMap 富集度map
     * @param boxPositionSet 宝箱位置set,x,y
     * @param dgNum 不符合的递归次数
     * @param fjdConfigMap 富集度配置MAP
     * @param maxDgNum 最大递归次数
     */
    public void createFourLaPositionsNew(Map<String, List<HsIslandPosition>> targetPositionMap, Map<String, Integer> fjdMap, Set<String> boxPositionSet, int dgNum, Map<Integer, Integer> fjdConfigMap, int maxDgNum) {
        //满足数量，返回
        if (targetPositionMap.size() / 4 >= this.bigPveNum) {
            return;
        }
        //超过不符合的递归次数，返回
        if (dgNum >= maxDgNum) {
            return;
        }
        //随机出一个起始点
        Set<String> latticeSet = new HashSet<>(this.mapTypeParamMap.get(HsIslandLatticeTypeEnum.LATTICE_TYPE_ONE.getType()));
        if (latticeSet.isEmpty()) {
            return;
        }
        //移除宝箱占领的
        if (boxPositionSet != null && !boxPositionSet.isEmpty()) {
            //移除宝箱的占用的坐标
            latticeSet.removeAll(boxPositionSet);
        }
        //移除已占用的位置
        latticeSet.removeAll(targetPositionMap.keySet());
        //随机出一个位置
        String startPosition = RandomHelper.getRandomElement(latticeSet);
        if (StringUtils.isNullOrEmpty(startPosition)) {
            return;
        }
        String[] startPositionArr = startPosition.split(",");
        int x = Integer.parseInt(startPositionArr[0]);
        int y = Integer.parseInt(startPositionArr[1]);
        //获取上面，右边，右上的3个坐标，组成4格组，判断是否都合法
        boolean flag = true;
        List<Point> points = PlotUtil.getAdjacentCoordinates(x, y);
        for (Point point : points) {
            Integer type = this.getPositionType(point.getKey2());
            if (type == null || type != HsIslandLatticeTypeEnum.LATTICE_TYPE_ONE.getType() ||
                    targetPositionMap.containsKey(point.getKey2()) || (boxPositionSet != null && boxPositionSet.contains(point.getKey2()))) {
                flag = false;
                break;
            }
        }
        if (!flag) {
            //不符合条件
            this.createFourLaPositionsNew(targetPositionMap, fjdMap, boxPositionSet, dgNum + 1, fjdConfigMap, maxDgNum);
        } else {
            //符合条件。4个格子注入MAP
            List<HsIslandPosition> positionList = new ArrayList<>();
            positionList.add(new HsIslandPosition(x, y));
            for (Point point : points) {
                positionList.add(new HsIslandPosition(point.getX(), point.getY()));
            }
            //所有坐标注入MAP
            for (HsIslandPosition position : positionList) {
                targetPositionMap.put(position.getKey2(), positionList);
            }
            //处理富集度
            this.fjdHandle(positionList, fjdMap, fjdConfigMap);
            //创建下一个四格
            this.createFourLaPositionsNew(targetPositionMap, fjdMap, boxPositionSet, 0, fjdConfigMap, maxDgNum);
        }
    }

    /**
     * 富集度处理
     * @param positionList
     * @param fjdMap
     */
    private void fjdHandle(List<HsIslandPosition> positionList, Map<String, Integer> fjdMap, Map<Integer, Integer> fjdConfigMap) {
        Set<String> eventPositionSet = this.mapTypeParamMap.get(HsIslandLatticeTypeEnum.LATTICE_TYPE_ONE.getType());
        int index = 0;
        for (HsIslandPosition position : positionList) {
            //获取扩展点
            Map<String, PointFjd> pointFjdMap = new HashMap<>();
            if (index == 0) {
                //获取左下3步扩展的坐标
                pointFjdMap = PlotUtil.expandPositions(position.getX(), position.getY(), 3, PlotUtil.Direction.LEFT_DOWN);
            }
            if (index == 1) {
                //获取左上3步扩展的坐标
                pointFjdMap = PlotUtil.expandPositions(position.getX(), position.getY(), 3, PlotUtil.Direction.LEFT_UP);
            }
            if (index == 2) {
                //获取右下3步扩展的坐标
                pointFjdMap = PlotUtil.expandPositions(position.getX(), position.getY(), 3, PlotUtil.Direction.RIGHT_DOWN);
            }
            if (index == 3) {
                //获取右上3步扩展的坐标
                pointFjdMap = PlotUtil.expandPositions(position.getX(), position.getY(), 3, PlotUtil.Direction.RIGHT_UP);
            }
            for (PointFjd pointFjd : pointFjdMap.values()) {
                //判断是否是事件格子
                if (!eventPositionSet.contains(pointFjd.getKey2())) {
                    continue;
                }
                //增加的value
                Integer addValue = fjdConfigMap.get(pointFjd.getDistance());
                if (addValue != null) {
                    //获取原value
                    int oldValue = fjdMap.getOrDefault(pointFjd.getKey2(), 0);
                    fjdMap.put(pointFjd.getKey2(), oldValue + addValue);
                }
            }
            index++;
        }
    }

//    /**
//     * 随机获取需要生成的4格事件起始点
//     * @return
//     */
//    public Set<String> getRandomFourLaPositions(Map<String, HsIslandBoxData> boxDataMap) {
//        //获取下宝箱坐标“,”隔开
//        HashSet<String> boxPositionSet = new HashSet<>();
//        if (boxDataMap != null) {
//            for (String position : boxDataMap.keySet()) {
//                String[] positionArr = position.split("_");
//                boxPositionSet.add(positionArr[0] + "," + positionArr[1]);
//            }
//        }
//        //4格起始点
//        Set<String> latticeSet = this.mapTypeParamMap.get(HsIslandLatticeTypeEnum.LATTICE_TYPE_FOUR.getType());
//        if (latticeSet != null && !boxPositionSet.isEmpty()) {
//            //移除宝箱的占用的坐标
//            latticeSet.removeAll(boxPositionSet);
//        }
//        return RandomHelper.selectRandomElements(latticeSet, this.bigPveNum);
//    }

//    /**
//     * 创建4格事件格子组
//     * @param boxDataMap 宝箱MAP,无宝箱为null
//     * @return
//     */
//    public Map<String, List<HsIslandPosition>> createFourLaPositions(Map<String, HsIslandBoxData> boxDataMap) {
//        Map<String, List<HsIslandPosition>> map = new ConcurrentHashMap<>();
//        //起始点
//        Set<String> startPositions = this.getRandomFourLaPositions(boxDataMap);
//        for (String  startPosition : startPositions) {
//            String[] startPositionArr = startPosition.split(",");
//            int x = Integer.parseInt(startPositionArr[0]);
//            int y = Integer.parseInt(startPositionArr[1]);
//            List<HsIslandPosition> positionList = new ArrayList<>();
//            positionList.add(new HsIslandPosition(x, y));
//            //获取上面，右边，右上的3个坐标，组成4格组
//            List<Point> points = PlotUtil.getAdjacentCoordinates(x, y);
//            for (Point point : points) {
//                positionList.add(new HsIslandPosition(point.getX(), point.getY()));
//            }
//            //所有坐标注入MAP
//            for (HsIslandPosition position : positionList) {
//                map.put(position.getKey(), positionList);
//            }
//        }
//        return map;
//    }

    /**
     * 判断是否可探索
     * @param x
     * @param y
     * @return
     */
    public boolean checkPositionCanExplore(int x, int y) {
        int type = this.mapParamMap.get(x + "," + y);
//        int type1 = this.mapParamMap.get(31 + "," + 23);
//        int type2 = this.mapParamMap.get(32 + "," + 23);
//        int type3 = this.mapParamMap.get(30 + "," + 22);
//        int type4 = this.mapParamMap.get(30 + "," + 21);
//        int type5 = this.mapParamMap.get(31 + "," + 20);
//        int type6 = this.mapParamMap.get(32 + "," + 20);
//        int type7 = this.mapParamMap.get(33 + "," + 22);
//        int type8 = this.mapParamMap.get(33 + "," + 21);
        if (HsIslandLatticeTypeEnum.checkCanExplore(type)) {
            return true;
        }
        return false;
    }
}
